package com.hulk.ratel.manage.wx.service;

import cn.hutool.core.bean.BeanUtil;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.google.common.base.Throwables;

import com.hulk.ratel.common.constant.enums.BussErrCode;
import com.hulk.ratel.common.exception.ManageRteException;
import com.hulk.ratel.common.exception.WebRteException;

import com.hulk.ratel.common.util.DateUtil;
import com.hulk.ratel.manage.bo.ErrcodeConvertBO;
import com.hulk.ratel.manage.bo.InitiativeScanPayReqBO;
import com.hulk.ratel.manage.bo.InitiativeScanPayRespBO;
import com.hulk.ratel.manage.commonutil.ErrorConvertUtil;
import com.hulk.ratel.manage.org.interfaces.IScanPayApplayService;
import com.hulk.ratel.manage.wx.constant.WxPayConstant;
import com.hulk.ratel.manage.wx.util.WxPayProperties;
import com.hulk.ratel.manage.wx.util.WxPayUtil;
import com.hulk.ratel.persistence.entity.LogTxnPayRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;


import lombok.NonNull;
import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author hulk
 * @version V1.0
 * @Description: 支付渠道接口:微信
 * @date 2017-09-05
 */
@Slf4j
@Service
public class OrderUnifyApplyWxService implements IScanPayApplayService {


    @Resource
    private WxPayProperties wxPayProperties;



    @Override
    public InitiativeScanPayRespBO doPay(@NonNull InitiativeScanPayReqBO bo, @NonNull LogTxnPayRecord record, String workId) {

        log.info("【微信支付统一下单-NATIVE】InitiativeScanPayReqBO: {},workId: {}.",bo,workId);
        InitiativeScanPayRespBO respBO = new InitiativeScanPayRespBO();
        WxPayUnifiedOrderResult wxResp = null;
        String mchId = wxPayProperties.getMchId();
        String appId = wxPayProperties.getAppId();
        String mchKey = wxPayProperties.getMchKey();
        String signType = wxPayProperties.getSignType();
        String notifyUrl = wxPayProperties.getNotifyUrl();
        String tradeType = WxPayConstant.WxConstant.TRADE_TYPE_NATIVE;
        String orgReqTime = DateUtil.getDateyyyyMMddHHmmss();
        String orgReqDate = DateUtil.getDateyyyyMMdd();
        try {


            //设置微信config
            WxPayConfig wxPayConfig = WxPayUtil.getWxPayConfig(mchId, appId, tradeType, mchKey, signType, null, notifyUrl);
            WxPayService wxPayService = new WxPayServiceImpl();
            wxPayService.setConfig(wxPayConfig);

            //构建微信请求对象
            WxPayUnifiedOrderRequest wxReq = new WxPayUnifiedOrderRequest();
            BeanUtil.copyProperties(bo, wxReq);
            wxReq.setAppid(appId);
            wxReq.setMchId(mchId);
            wxReq.setSubMchId("1509652781");
            wxReq.setDeviceInfo(bo.getTerminalNo());
            wxReq.setNonceStr(bo.getWorkId());
            wxReq.setBody(bo.getSubject());
            wxReq.setDetail(bo.getDesc());
            wxReq.setOutTradeNo(bo.getWorkId());
            wxReq.setTotalFee(Integer.parseInt(bo.getTotalAmt()));
            wxReq.setSpbillCreateIp(bo.getTerminalIp());
            wxReq.setTimeStart(orgReqTime);
            wxReq.setTimeExpire(bo.getExpireTime());
            wxReq.setNotifyUrl(notifyUrl);
            wxReq.setTradeType(tradeType);
            wxReq.setProductId("123");
            wxReq.checkAndSign(wxPayConfig);
            //更新record请求机构流水数据
            record.setOrgReqTime(orgReqTime);
            record.setOrgReqDate(orgReqDate);

            log.info("【微信支付统一下单请求-NATIVE】WxPayUnifiedOrderRequest: {},workId: {}.",wxReq,workId);
             wxResp = wxPayService.unifiedOrder(wxReq);
            if (!Optional.ofNullable(wxResp).isPresent()) {
                log.error("【微信支付统一下单失败-NATIVE】WxPayUnifiedOrderResult: {},workId: {}.",wxResp,workId);
                return null;
            }
            //验证签名直接抛出异常
            wxResp.checkResult(wxPayService,  null,false);
            log.info("【微信支付统一下单成功-NATIVE】WxPayUnifiedOrderResult: {},workId: {}.",wxResp,workId);
            //更新record响应机构流水数据
            record.setOrgRespDate(DateUtil.getDateyyyyMMdd());
            record.setOrgRespTime(DateUtil.getDateyyyyMMddHHmmss());

            //微信返回信息处理转换
            if(WxPayConstant.RETURN_CODE_SUCCESS.equals(wxResp.getReturnCode())){
                if (WxPayConstant.RESULT_CODE_SUCCESS.equals(wxResp.getResultCode())) {
                    BeanUtil.copyProperties(wxResp, respBO);
                    respBO.setRespCode(BussErrCode.S_0.getErrCode());
                    respBO.setRespMsg(BussErrCode.S_0.getErrDesc());
                    respBO.setQrCode(wxResp.getCodeURL());
                    respBO.setRespFlag(true);
                    return respBO;
                } else {
                    BeanUtil.copyProperties(wxResp, respBO);
                    ErrcodeConvertBO errcodeConvertBO = ErrorConvertUtil.convertErrCode(bo.getOrgCode(), wxResp.getErrCode());
                    respBO.setRespCode(errcodeConvertBO.getRespCode());
                    respBO.setRespMsg(errcodeConvertBO.getRespDesc());
                    respBO.setRespFlag(false);
                    return respBO;
                }
            }else {
                throw new ManageRteException(workId,0,wxResp.getErrCode()+": "+wxResp.getErrCodeDes());
            }

        } catch (WxPayException e) {
            log.error("【微信支付统一下单异常-NATIVE】,err_code:{},err_code_des:{},WxPayException:{}", e.getErrCode(),e.getErrCodeDes(), Throwables.getStackTraceAsString(e));
            throw new ManageRteException(workId,0,wxResp.getErrCode()+": "+wxResp.getErrCodeDes());
        } catch (Exception e) {
            log.error("微信支付统一下单异常-NATIVE", e);
            throw e;
        }
    }
}
